package com.msk.sys.utils;

import com.alibaba.fastjson2.JSONObject;
import com.msk.common.utils.StringUtils;
import com.msk.common.utils.sign.Md5Utils;
import com.msk.sys.domain.LatLng;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

/** 百度地图工具类
 * @Description
 * @Author zlf
 * @Date 2022/12/30 16:24
 */
public class BaiduMapUtil {

    private static final Logger log = LoggerFactory.getLogger(BaiduMapUtil.class);

    public static String loadJSON (String url) {
        StringBuilder json = new StringBuilder();
        try {
            URL oracle = new URL(url);
            URLConnection yc = oracle.openConnection();
            BufferedReader in = new BufferedReader(new InputStreamReader(
                    yc.getInputStream()));
            String inputLine = null;
            while ( (inputLine = in.readLine()) != null) {
                json.append(inputLine);
            }
            in.close();
        } catch (MalformedURLException e) {
        } catch (IOException e) {
        }
        return json.toString();
    }

    /**根据地址获取经纬度
     * @Description:
     * @Author: zlf
     * @Date: 2023/1/1 22:13
     * @param address:
     * @return: java.util.Map<java.lang.String,java.lang.Double>
     **/
    public static Map<String,Double> getLngAndLat(String address){
        Map<String, Double> map = new HashMap<String, Double>();
        String ak = DictMskUtils.getDictValue("ak", "show_map","pjTELZKQuGAbAW1pYoZSjEioW19vleIG");
        String url = "https://api.map.baidu.com/geocoding/v3/?address=" + address + "&output=json&ak=" + ak;
        String json = loadJSON(url);
        if (StringUtils.isNotEmpty(json)) {
            JSONObject obj = JSONObject.parseObject(json);
            if ("0".equals(obj.getString("status"))) {
                double lng = obj.getJSONObject("result").getJSONObject("location").getDouble("lng");
                double lat = obj.getJSONObject("result").getJSONObject("location").getDouble("lat");
                map.put("lng", lng);
                map.put("lat", lat);
            } else {
                log.info("据地址获取经纬度接口异常:{}", json);
            }
        } else {
            log.info("据地址获取经纬度接口异常:数据返回为空");
        }
        return map;
    }

    public static Map<String,Double> getLngAndLatSn(String address){
        Map<String, Double> map = new HashMap<String, Double>();
        String ak = "XUrYNCbSOvWXYVEFZvL7wvpe7HTXpASY";
        Map paramsMap = new LinkedHashMap<String, String>();
        paramsMap.put("address", address);
        paramsMap.put("output", "json");
        paramsMap.put("ak", ak);
        String sn = getBaiduSn(paramsMap);
        String url = "https://api.map.baidu.com/geocoding/v3/?address=" + address + "&output=json&ak=" + ak + "&sn=" + sn;
        String json = loadJSON(url);
        System.out.println(json);
        if (StringUtils.isNotEmpty(json)) {
            JSONObject obj = JSONObject.parseObject(json);
            if ("0".equals(obj.getString("status"))) {
                double lng = obj.getJSONObject("result").getJSONObject("location").getDouble("lng");
                double lat = obj.getJSONObject("result").getJSONObject("location").getDouble("lat");
                map.put("lng", lng);
                map.put("lat", lat);
            } else {
                System.out.println("未找到相匹配的经纬度！");
            }
        } else {
            System.out.println("未找到相匹配的经纬度！");
        }
        return map;
    }

    public static String getBaiduSn(Map<String, String> paramsMap) {
        String sn = "";
        try {
            String sk = "huo8mMZbAIhOuGxoQe1VCDW3wHSUFGbt";
            String paramsStr = toQueryString(paramsMap);
            String wholeStr = new String("/geocoding/v3/?" + paramsStr + sk);
            // 对上面wholeStr再作utf8编码
            String tempStr = URLEncoder.encode(wholeStr, "UTF-8");
            sn = Md5Utils.MD5(tempStr);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return sn;
    }

    /**
     * 计算两点之间距离
     * @param start
     * @param end
     * @return 米
     */
    public static double getDistance(LatLng start, LatLng end){
        double lat1 = (Math.PI/180)*start.latitude;
        double lat2 = (Math.PI/180)*end.latitude;

        double lon1 = (Math.PI/180)*start.longitude;
        double lon2 = (Math.PI/180)*end.longitude;

        //地球半径
        double R = 6371;

        //两点间距离 km，如果想要米的话，结果*1000就可以了
        double d =  Math.acos(Math.sin(lat1)*Math.sin(lat2)+Math.cos(lat1)*Math.cos(lat2)*Math.cos(lon2-lon1))*R;
        d = d*1000;
        return d;
    }

    /** 计算两地的距离
     * @Description:
     * @Author: zlf
     * @Date: 2022/12/30 16:33
     * @param address1:
     * @param address2:
     * @return: double
     **/
    public static double getDistanceForAddress(String address1, String address2){
        Map<String, Double> map1 = getLngAndLat(address1);
        Map<String, Double> map2 = getLngAndLat(address2);
        LatLng latLng1 =new LatLng(map1.get("lng"),map1.get("lat"));
        LatLng latLng2 =new LatLng(map2.get("lng"),map2.get("lat"));
        double a = getDistance(latLng1, latLng2);
        return a;
    }

    /**计算两个坐标的距离
     * @Description:
     * @Author: zlf
     * @Date: 2022/12/30 16:41
     * @param latLng1:
     * @param latLng2:
     * @return: double
     **/
    public static double getDistanceForPoint(LatLng latLng1, LatLng latLng2){
        double a = getDistance(latLng1, latLng2);
        return a;
    }

    /**
     * 对Map内所有value作utf8编码，拼接返回结果
     * @param data
     * @return
     * @throws UnsupportedEncodingException
     */
    public static String toQueryString(Map<?, ?> data) {
        StringBuffer queryString = new StringBuffer();
        try {
            for (Map.Entry<?, ?> pair : data.entrySet()) {
                queryString.append(pair.getKey()).append("=");
                String ss[] = String.valueOf(pair.getValue()).split(",");
                if (ss.length > 1) {
                    for (String s : ss) {
                        queryString.append(URLEncoder.encode(s, "UTF-8")).append(",");
                    }
                    queryString.deleteCharAt(queryString.length()-1);
                    queryString.append("&");
                } else {
                    queryString.append(URLEncoder.encode(String.valueOf(pair.getValue()), "UTF-8"));
                    queryString.append("&");
                }
            }
            if (queryString.length() > 0) {
                queryString.deleteCharAt(queryString.length() - 1);
            }
            return queryString.toString();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return "";
    }

    public static void main(String[] args) {
        Map<String, Double> map1 = getLngAndLat("陕西省西安市雁塔区科技六路数字空间");
        System.out.println(map1);
    }
}
